﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using T.FAS.Runtime.Metadata.Entity;
using T.ServiceComponent.DAC.Service;
using T.ServiceComponent.DataAccessEx.Core;

namespace T.FAS.Runtime.Metadata.Dao
{
    public class MetaDataCheckOutDao : DaoService<MetaDataCheckOut>
    {
        public MetaDataCheckOutDao(string db = "TFAS") : base()
        {
            this.DBName = db;
        }

        public override string IDColumnName
        {
            get
            {
                return "ID";
            }
        }

        public override string TableName
        {
            get
            {
                return "Meta_CheckOut";
            }
        }
        public override List<string> ExceptColumnName
        {
            get
            {
                return new List<string>()
                {
                    "MetaData",
                    "MetaDataName",
                    "CreateMetaDtaJsonSeriaSetting",
                    "children"
                };
            }
        }
        public List<string> GetMetaDataCheckOutUser(string metaDataID, string projectBranchID, string userID)
        {

            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@MetaDataID", TDbDataType.VarChar, metaDataID));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            string sqlCondition = "CheckOutState=0 AND MetaDataID=@MetaDataID AND ProjectBranchID=@ProjectBranchID";
            if (string.IsNullOrEmpty(userID) == false)
            {
                sqlCondition = string.Format("{0} AND CheckOutUserID!=@UserID", sqlCondition);
                paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            }
            var ds = this.DB.ExecuteDataSet(string.Format("select CheckOutUserName from {0} WHERE {1}", TableName, sqlCondition), paramsList.ToArray());
            List<string> userList = new List<string>();
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                foreach (DataRow row in ds.Tables[0].Rows)
                {
                    userList.Add(Convert.ToString(row["CheckOutUserName"]));
                }
            }
            return userList;
        }
        public List<Tuple<string, string>> GetMetaDataCheckOutUser2(string metaDataID, string projectBranchID, string userID)
        {

            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@MetaDataID", TDbDataType.VarChar, metaDataID));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            string sqlCondition = "CheckOutState=0 AND MetaDataID=@MetaDataID AND ProjectBranchID=@ProjectBranchID";
            if (string.IsNullOrEmpty(userID) == false)
            {
                sqlCondition = string.Format("{0} AND CheckOutUserID!=@UserID", sqlCondition);
                paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            }
            var ds = this.DB.ExecuteDataSet(string.Format("select CheckOutUserName,CheckOutUserID from {0} WHERE {1}", TableName, sqlCondition), paramsList.ToArray());
            List<Tuple<string, string>> userList = new List<Tuple<string, string>>();
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                foreach(DataRow row in ds.Tables[0].Rows) {
                    userList.Add(new Tuple<string, string>(Convert.ToString(row["CheckOutUserName"]), Convert.ToString(row["CheckOutUserID"])));
                }
            }
            return userList;
        }
        public string GetCheckOutMetaDataContent(string metaDataID, string projectBranchID, string userID) {

            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@MetaDataID", TDbDataType.VarChar, metaDataID));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            string sqlCondition = "MetaDataID=@MetaDataID AND ProjectBranchID=@ProjectBranchID";
            if (string.IsNullOrEmpty(userID) == false)
            {
                sqlCondition = string.Format("{0} AND CheckOutUserID=@UserID", sqlCondition);
                paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            }
            sqlCondition = string.Format("{0} AND CheckOutState in (0,5)", sqlCondition);
            var ds = this.DB.ExecuteDataSet(string.Format("select content.MetaDataContent from {0} checkout Left Join Meta_CheckOutContent content on checkout.ID = content.CheckOutID WHERE {1}", TableName, sqlCondition), paramsList.ToArray());
            var metaDataContent = "";
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                metaDataContent = Convert.ToString(ds.Tables[0].Rows[0]["MetaDataContent"]);
            }
            return metaDataContent;
        }

        public bool IfCurUserCheckoutThisMeta(string metaDataID, string projectBranchID, string userID)
        {
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@MetaDataID", TDbDataType.VarChar, metaDataID));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            string sqlCondition = "(MetaDataID=@MetaDataID or MetaDataCode=@MetaDataID) AND ProjectBranchID=@ProjectBranchID";
            sqlCondition = string.Format("{0} AND CheckOutUserID=@UserID", sqlCondition);
            sqlCondition = string.Format("{0} AND CheckOutState in (0,5)", sqlCondition);
            paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            string sql = "select 1 from {0} checkout WHERE {1}";
            var obj = this.DB.ExecuteScalar(string.Format(sql, TableName, sqlCondition), paramsList.ToArray());
            if (obj == null || obj == DBNull.Value)
            {
                return false;
            }
            else
            {
                if (!int.TryParse(obj.ToString(), out int val))
                {
                    return false;
                }
            }
            return true;
        }

        public MetaDataCheckOut GetCheckOutMetaData(string metaDataID, string projectBranchID, string userID, string checkOutState="")
        {

            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@MetaDataID", TDbDataType.VarChar, metaDataID));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            string sqlCondition = "MetaDataID=@MetaDataID AND ProjectBranchID=@ProjectBranchID";            
            if (string.IsNullOrEmpty(userID) == false)
            {
                sqlCondition = string.Format("{0} AND CheckOutUserID=@UserID", sqlCondition);
                paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            }
            if (string.IsNullOrEmpty(checkOutState) == false)
            {
                sqlCondition = string.Format("{0} AND CheckOutState=@CheckOutState", sqlCondition);
                paramsList.Add(this.DB.MakeInParam("@CheckOutState", TDbDataType.VarChar, checkOutState));
            }
            else {
                sqlCondition = string.Format("{0} AND CheckOutState in (0,1,5)", sqlCondition);
            }
            var ds = this.DB.ExecuteDataSet(string.Format("select checkout.ID,MetaDataID,MetaDataCode,ProjectBranchID,MetaTypeID,MetaDataVersionID,content.MetaDataContent,CheckOutState,CheckOutUserID,CheckOutUserName,Description,Creator,CreateTime,LastModifier,LastModifyTime from {0} checkout Left Join Meta_CheckOutContent content on checkout.ID = content.CheckOutID WHERE {1}", TableName, sqlCondition), paramsList.ToArray());
            MetaDataCheckOut checkOut = null;
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                checkOut = ConvertToObject(this.Columns, ds.Tables[0].Rows[0]);
            }
            return checkOut;
        }
        public MetaDataCheckOut GetCheckOutMetaDataWithCode(string metaDataIDOrCode, string projectBranchID, string userID)
        {

            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@MetaDataID", TDbDataType.VarChar, metaDataIDOrCode));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            string sqlCondition = "(MetaDataID=@MetaDataID Or MetaDataCode=@MetaDataID) AND ProjectBranchID=@ProjectBranchID";
            if (string.IsNullOrEmpty(userID) == false)
            {
                sqlCondition = string.Format("{0} AND CheckOutUserID=@UserID", sqlCondition);
                paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            }            
            sqlCondition = string.Format("{0} AND CheckOutState in (0,1,5)", sqlCondition);
            
            var ds = this.DB.ExecuteDataSet(string.Format("select checkout.ID,MetaDataID,MetaDataCode,ProjectBranchID,MetaTypeID,MetaDataVersionID,content.MetaDataContent,CheckOutState,CheckOutUserID,CheckOutUserName,Description,Creator,CreateTime,LastModifier,LastModifyTime from {0} checkout Left Join Meta_CheckOutContent content on checkout.ID = content.CheckOutID WHERE {1}", TableName, sqlCondition), paramsList.ToArray());
            MetaDataCheckOut checkOut = null;
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                checkOut = ConvertToObject(this.Columns, ds.Tables[0].Rows[0]);
            }
            return checkOut;
        }
        /// <summary>
        /// 获取待签入的记录，状态为0（元数据签出）、1（元数据新建）、5（元数据删除中）
        /// </summary>
        /// <param name="projectBranchID"></param>
        /// <param name="userID"></param>
        /// <returns></returns>
        public List<MetaDataCheckOut> GetAllCheckOutMetaData(string projectBranchID, string userID, bool containNew) {
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            string sqlCondition = "ProjectBranchID=@ProjectBranchID AND CheckOutUserID=@UserID AND CheckOutState in (0,1,5) AND  MetaTypeID<>'Project'";
            if (containNew == false) {
                sqlCondition = "ProjectBranchID=@ProjectBranchID AND CheckOutUserID=@UserID AND CheckOutState in (0,5) ";
            }
            paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            //var ds = this.DB.ExecuteDataSet(string.Format("select checkout.ID,MetaDataID,MetaDataCode,ProjectBranchID,MetaDataVersionID,content.MetaDataContent,CheckOutState,CheckOutUserID,CheckOutUserName,Description,Creator,CreateTime,LastModifier,LastModifyTime from {0} checkout Left Join Meta_CheckOutContent content on checkout.ID = content.CheckOutID WHERE {1} order by LastModifyTime DESC", TableName, sqlCondition), paramsList.ToArray());
            var ds = this.DB.ExecuteDataSet(string.Format("select ID,MetaDataID,MetaDataCode,ProjectBranchID,MetaTypeID,MetaDataVersionID,'' MetaDataContent,CheckOutState,CheckOutUserID,CheckOutUserName,Description,Creator,CreateTime,LastModifier,LastModifyTime from {0} WHERE {1} order by LastModifyTime DESC", TableName, sqlCondition), paramsList.ToArray());
            List<MetaDataCheckOut> list = new List<MetaDataCheckOut>();
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                foreach (DataRow row in ds.Tables[0].Rows) {
                    list.Add(ConvertToObject(this.Columns, row));
                }                
            }
            return list;
        }

        public void UpdateState(string metaDataID, string projectBranchID, string userID, int state)
        {
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@MetaDataID", TDbDataType.VarChar, metaDataID));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            paramsList.Add(this.DB.MakeInParam("@CheckOutState", TDbDataType.Int, state));
            paramsList.Add(this.DB.MakeInParam("@LastModifyTime", TDbDataType.DateTime, DateTime.Now));

            this.DB.ExecSqlStatement("Update Meta_CheckOut Set CheckOutState=@CheckOutState,LastModifyTime=@LastModifyTime WHERE MetaDataID=@MetaDataID AND ProjectBranchID=@ProjectBranchID AND CheckOutUserID=@UserID AND CheckOutState in (0,1,5) ", paramsList.ToArray());
        }
        public void UpdateState(int state, string checkOutID)
        {
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@CheckOutID", TDbDataType.VarChar, checkOutID));
            paramsList.Add(this.DB.MakeInParam("@CheckOutState", TDbDataType.Int, state));
            paramsList.Add(this.DB.MakeInParam("@LastModifyTime", TDbDataType.DateTime, DateTime.Now));

            this.DB.ExecSqlStatement("Update Meta_CheckOut Set CheckOutState=@CheckOutState,LastModifyTime=@LastModifyTime WHERE ID=@CheckOutID ", paramsList.ToArray());
        }
        public void BatchUpdateState(string metaDataIds, string projectBranchID, string userID, int state) {
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            //paramsList.Add(this.DB.MakeInParam("@MetaDataIDs", TDbDataType.VarChar, metaDataIds));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            paramsList.Add(this.DB.MakeInParam("@CheckOutState", TDbDataType.Int, state));

            this.DB.ExecSqlStatement(string.Format("Update Meta_CheckOut Set CheckOutState=@CheckOutState WHERE MetaDataID in ({0}) AND ProjectBranchID=@ProjectBranchID AND CheckOutUserID=@UserID",metaDataIds), paramsList.ToArray());
        }

        public void DeleteCheckOutMetaData(string metaDataID, string projectBranchID, string userID) {
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@MetaDataID", TDbDataType.VarChar, metaDataID));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));
            paramsList.Add(this.DB.MakeInParam("@UserID", TDbDataType.VarChar, userID));
            this.DB.ExecSqlStatement("Delete FROM Meta_CheckOut WHERE MetaDataID=@MetaDataID AND ProjectBranchID=@ProjectBranchID AND CheckOutUserID=@UserID AND CheckOutState!=-1 ", paramsList.ToArray());
        }

        public void UpdateCheckOut(string metaDataID, string metaDataCode, string metaDataVersionID, string projectBranchID, string userID, DateTime now)
        {
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@MetaDataCode", TDbDataType.VarChar, metaDataCode));
            paramsList.Add(this.DB.MakeInParam("@MetaDataVersionID", TDbDataType.VarChar, metaDataVersionID));
            paramsList.Add(this.DB.MakeInParam("@LastModifyTime", TDbDataType.DateTime, now));
            paramsList.Add(this.DB.MakeInParam("@MetaDataID", TDbDataType.VarChar, metaDataID));
            paramsList.Add(this.DB.MakeInParam("@CheckOutUserID", TDbDataType.VarChar, userID));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));

            this.DB.ExecSqlStatement("Update Meta_CheckOut Set MetaDataCode=@MetaDataCode,MetaDataVersionID=@MetaDataVersionID,LastModifyTime=@LastModifyTime WHERE MetaDataID=@MetaDataID AND ProjectBranchID=@ProjectBranchID AND CheckOutUserID=@CheckOutUserID AND CheckOutState!=-1", paramsList.ToArray());
        }
        public void UpdateCheckOutUserID(string userID, string userName, string projectBranchID)
        {
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            paramsList.Add(this.DB.MakeInParam("@CheckOutUserName", TDbDataType.VarChar, userName));
            paramsList.Add(this.DB.MakeInParam("@CheckOutUserID", TDbDataType.VarChar, userID));
            paramsList.Add(this.DB.MakeInParam("@ProjectBranchID", TDbDataType.VarChar, projectBranchID));

            this.DB.ExecSqlStatement("Update Meta_CheckOut Set CheckOutUserID=@CheckOutUserID, CheckOutUserID=@CheckOutUserID WHERE ProjectBranchID=@ProjectBranchID AND CheckOutState!=-1", paramsList.ToArray());
        }
    }
}
